/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package exmtgproj;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

/**
 *
 * @author marcus ahlen
 */
public class CardGenerator implements Statics {

    private static int deckSizeLimit = 196 / 2;

    /**
     * Går igenom en xml fil och genererar en CardList av innehållet
     * @param file
     * @return
     */
    static CardList getDeck(File file) {
        CardList resDeck = new CardList();
        Scanner scan;
        //testar om filen finns
        try {
            scan = new Scanner(file);
            System.out.println("File found! " + file.getName());
        } catch (FileNotFoundException ex) {
            System.out.println("FileNotFound");
            return null;
        }
        scan.nextLine();    //hoppar över <cards>
        resDeck.name = getTag(scan.nextLine());    //<name></name>
        getTag(scan.nextLine());    //hoppar över <key></key>
        getTag(scan.nextLine());    //hoppar över <type></type>
        scan.nextLine();    //hoppar över <properties/>
        scan.nextLine();    //hoppar över <list>

        int cardIndex = 0;
        while (scan.hasNext()) {
            //<mcp> står alltid på raden om det finns fler kort
            if (!scan.nextLine().contains("<mcp>") || resDeck.size() >= deckSizeLimit) {
                System.out.println("Card limit reached! Loaded " + resDeck.size() + " cards..");
                return resDeck;
            } else {
                scan.nextLine();    //hoppar över <card>
            }
            int id = Integer.parseInt(getTag(scan.nextLine()));//<id>18723</id>
            String name = getTag(scan.nextLine());//<name>Name Here</name>
            System.out.println(name);
            String manacost = getTag(scan.nextLine());//<cost>{X}{R}{R}</cost>
            boolean colorless = true;
            byte[] cost = new byte[COLORS];
            boolean[] color = new boolean[COLORS];
            boolean xCost = false;
            int number = 1;
            if (manacost.length() > 1) {
                if (Character.isDigit(manacost.charAt(number))) {
                    byte cCost = 0;
                    for (; Character.isDigit(manacost.charAt(number)); number++) {  //{11} -> 11
                        cCost *= 10;
                        cCost += Byte.parseByte("" + manacost.charAt(number));
                    }
                    number += 2;
                    cost[c] = cCost;
                }
                //om det finns en manacost                                    1   2  3
                for (; number < manacost.length(); number += 3) {          //{11}{G}{U}
                    //om programmet kommer hit betyder det att
                    //det finns något mer efter den färglösa manan
                    switch (manacost.charAt(number)) {
                        case 'W':
                            cost[w]++;
                            color[w] = true;
                            colorless = false;
                            break;
                        case 'U':
                            cost[u]++;
                            color[u] = true;
                            colorless = false;
                            break;
                        case 'B':
                            cost[b]++;
                            color[b] = true;
                            colorless = false;
                            break;
                        case 'R':
                            cost[r]++;
                            color[r] = true;
                            colorless = false;
                            break;
                        case 'G':
                            cost[g]++;
                            color[g] = true;
                            colorless = false;
                            break;
                        case 'X':
                            xCost = true;
                            break;
                    }
                }
            }
            color[c] = colorless;
            Scanner types = new Scanner(getTag(scan.nextLine()));//<type>SuperType Type -
            boolean[] type = new boolean[TYPES];

            boolean legendary = false;
            boolean basic = false;

            while (types.hasNext()) {
                String str = types.next();
                //efter ett - kommer alltid subtyper
                if (str.equals("-")) {
                    break;
                }
                if (str.equals("Land")) {
                    type[land] = true;
                } else if (str.equals("Creature")) {
                    type[creature] = true;
                } else if (str.equals("Artifact")) {
                    type[artifact] = true;
                } else if (str.equals("Planeswalker")) {
                    type[planeswalker] = true;
                } else if (str.equals("Sorcery")) {
                    type[sorcery] = true;
                } else if (str.equals("Instant")) {
                    type[instant] = true;
                } else if (str.equals("Enchantment")) {
                    type[enchantment] = true;
                } else if (str.equals("Legendary")) {
                    legendary = true;
                } else if (str.equals("Basic")) {
                    basic = true;
                }
            }
            ArrayList<String> subtype = new ArrayList<String>();// SubType</type>
            while (types.hasNext()) {
                subtype.add(types.next());
            }

            int power = 0; //<power>7</power>
            //power kan vara "" därför behövs felhantering
            try {
                power = Byte.parseByte(getTag(scan.nextLine()));
            } catch (Exception e) {
            }


            int toughness = 0; //<toughness>11</toughness>
            try {
                toughness = Byte.parseByte(getTag(scan.nextLine()));
            } catch (Exception e) {
            }

            String edition = getTag(scan.nextLine());//<edition>Magic 2010</edition
            String rarity = getTag(scan.nextLine()); //<rarity>Rare</rarity>

            String[] oracle = parseOracle(getTag(scan.nextLine())); //<oracleText>Flying&lt;br&gt;Haste</oracleText>
            for (int i = 0; i < oracle.length; i++) {
                oracle[i] = makeRows(oracle[i]);
            }

            Ability cast = new Ability() {
            };
            cast.cost = cost;
            cast.xCost = xCost;
            cast.spellText = "Cast this";
            ArrayList<Ability> abilities = new ArrayList<Ability>();
            ArrayList<Ability> statics = new ArrayList<Ability>();
            ArrayList<Ability>[] events = new ArrayList[EVENTS];
            for (ArrayList<Ability> e : events) {
                e = new ArrayList<Ability>();
            }

            for (int i = 0;
                    i < oracle.length;
                    i++) {
                if (oracle[i].contains(":")) {
                    abilities.add(new Ability() {
                    });
                    abilities.get(abilities.size() - 1).spellText = oracle[i];
                } else if (isTriggered(oracle[i])) {
                } else {
                    statics.add(new Ability() {
                    });
                    statics.get(statics.size() - 1).spellText = oracle[i];
                }
            }

            cast.events.add(new AbilityEvent() {

                @Override
                int resolve(Card card, Targetable[] target) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }

                @Override
                Targetable[] target() {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });

            getTag(scan.nextLine());    //hoppar över <dbprice></dbprice>
            scan.nextLine();    //hoppar över </card>


            int count = Integer.parseInt(getTag(scan.nextLine())); //<count>4</count>

            getTag(scan.nextLine());    //hoppar över <price></price>
            if (scan.nextLine().contains("<comment>")) {
                scan.nextLine();    //hoppar över <location></location>
            }
            getTag(scan.nextLine());    //hoppar över <ownership></ownership>
            scan.nextLine();      //hoppar över </mcp>

            //lägger in all information i nya kort
            for (int i = 0; i < count; i++) {
                Card card = new Card(name);
                card.id = id;
                card.cast = cast;
                card.color = color;
                card.type = type;
                card.subtype = subtype;
                card.power = power;
                card.toughness = toughness;
                card.edition = edition;
                card.rarity = rarity;
                card.abilities = abilities;
                card.events = events;
                card.statics = statics;
                card.legendary = legendary;
                card.basic = basic;
                card.initImg();
                resDeck.add(card);
                //om deck storleks gränsen nås slutar programmet lägga till kopior
                if (resDeck.size() >= deckSizeLimit) {
                    break;
                }
                cardIndex++;
            }
        }
        return null;
    }

    private static boolean isTriggered(String string) {
        return false;
    }
    static byte ID = 0;
    static byte INIT = 0;
    static byte HAND = 1;
    static byte STACK = 2;
    static byte ENTERS = 3;
    static byte PLAY = 4;
    static byte ATTACK = 5;
    static byte BLOCK = 6;
    static byte LEAVEPLAY = 7;
    static byte GRAVE = 8;
    static byte DESTROY = 9;
    static byte SACRIFICE = 10;
    static byte[] a = new byte[11];

    /**
     * 
     * @param list en lista med listor av typen string
     * @param index index för listan
     * @param string vad som ska läggas till i slutet på nuvarande string i listan
     */
    /*static private void addTail(ArrayList<String> list, byte index, String string) {
    list.set(index, list.get(index) + string);
    }*/
    /**
     * Hämtar en string inom två taggar
     * @param s
     * @return
     */
    private static String getTag(String res) {
        int i = 1;
        for (; i < res.length(); i++) {
            if (res.charAt(i) == '>') {
                break;
            }
        }
        int j = ++i;
        for (; j < res.length(); j++) {
            if (res.charAt(j) == '<') {
                break;
            }
        }
        try {
            res = res.substring(i, j);
        } catch (Exception e) {
            res = "";
        }
        res = res.replace("&apos;", "'").replace("&quot;", "\"").replace("Ã†", "Æ").replace("&lt;i&gt;", "").replace("&lt;/i&gt;", "");
        return res;
    }

    private static String makeRows(String res) {
        Scanner it = new Scanner(res);
        res = "";
        int chars = 0;
        int max = 35;
        while (it.hasNext()) {
            String next = it.next();
            if (next.contains("&lt;br&gt;")) {
                break;
            }
            /*if (chars + next.length() > max) {  //om texten som läggs på kommer hamna utanför bilden
            res += "\n";                    //ny rad
            chars = 0;
            }
            chars += next.length() + 1;*/
            res += next;
            if (it.hasNext()) {
                res += " ";
            }
        }
        return res;
    }

    private static String[] parseOracle(String nextTag) {
        String[] res = nextTag.split("&lt;br&gt;");
        for (int i = 0; i < res.length; i++) {
        }
        return res;
    }

    static CardList getDeck(String file) {
        return getDeck(file);
    }
}
